import { MD5 } from "crypto-js";

// 字符替换
const replaceData = val => {
  return val.replace(/[()*'!！~]/g, match => {
    const chars = {
      "(": "%28",
      ")": "%29",
      "'": "%27",
      "*": "%2A",
      "!": "%21",
      "！": "%21",
      "~": "%7E"
    };
    return chars[match];
  });
};

const generateSortedParamsWithEncoding = (params, timestamp, random) => {
  const obj = {
    ...params,
    PZTimestamp: timestamp,
    Random: random
  };

  // 获取所有参数的键，并按照ASCII码顺序排序
  const sortedKeys = Object.keys(obj).sort();

  // 对每个键值对进行encodeURIComponent编码，然后用&连接
  const encodedParams = sortedKeys
    .map(key => {
      return `${encodeURIComponent(key)}=${encodeURIComponent(obj[key])}`;
    })
    .join("&");

  return encodedParams;
};

// 工具函数：解析URL查询字符串为对象
const parseQueryParams = url => {
  const queryParams = {};
  const queryString = url.split("?")[1];
  if (queryString) {
    queryString.split("&").forEach(param => {
      const [key, value] = param.split("=");
      queryParams[decodeURIComponent(key)] = decodeURIComponent(value || "");
    });
  }
  return queryParams;
};
// json转换
const parseJSON = str => {
  try {
    return JSON.parse(JSON.stringify(str));
  } catch (e) {
    return str;
  }
};
//接口参数签名
export const getSignature = config => {
  const { method, data, params } = config;
  const isGet = method.toLowerCase() === "get";
  // 时间戳
  const Timestamp = new Date().getTime();
  // 六位随机数
  const Random = Math.floor(Math.random() * (999999 - 100000 + 1)) + 100000;
  // 新参数
  const paramData = {
    ...parseJSON(isGet ? params : data),
    ...parseQueryParams(config.url)
  };
  // 签名（三个默认参数）
  let Sign = `PZTimestamp=${Timestamp}&Random=${Random}&accessKey=3qXyB7uf`;

  if (paramData) {
    if (!isGet) {
      Sign = replaceData(
        `PZTimestamp=${Timestamp}&Random=${Random}&${0x7fffffff}=${encodeURIComponent(JSON.stringify(paramData))}&accessKey=3qXyB7uf`
      );
    } else {
      Sign = replaceData(
        `${generateSortedParamsWithEncoding(paramData, Timestamp, Random)}&accessKey=3qXyB7uf`
      );
    }
  }
  return {
    PZTimestamp: Timestamp,
    Sign: MD5(Sign).toString(),
    Random
  };
};
